home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Magnum One
/
Magnum One (Mid-American Digital) (Disc Manufacturing).iso
/
d20
/
pvert.arc
/
BMG.C
< prev
next >
Wrap
Text File
|
1992-01-15
|
4KB
|
135 lines
/*
* bmg.c -> Boyer-Moore-Gosper search routines
*
* Adapted from:
* Boyer/Moore/Gosper-assisted 'egrep' search, with delta0 table as in
* original paper (CACM, October, 1977). No delta1 or delta2. According to
* experiment (Horspool, Soft. Prac. Exp., 1982), delta2 is of minimal
* practical value. However, to improve for worst case input, integrating
* the improved Galil strategies (Apostolico/Giancarlo, Siam. J. Comput.,
* February 1986) deserves consideration.
*
* James A. Woods Copyright (c) 1986
* NASA Ames Research Center
*
* 29 April 1986 Jeff Mogul Stanford
* Adapted as a set of subroutines for use by a program. No
* regular-expression support.
*
* 29 August 1986 Frank Whaley Beyond Words
* Trimmed for speed and other dirty tricks.
*/
#ifdef OS2
#define INCL_DOS
#include <os2.h>
#endif
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "bmg.h"
/*
* bmgCompile() -> compile Boyer-Moore delta table
*
* bmgCompile() compiles the delta table for the given search string, and
* initializes the search argument structure. This structure must be
* passed to the bmgSearch() function described below.
*/
void bmgCompile(char *pat, bmgARG *arg, int ignore)
{
int i, /* general ctr */
patlen; /* pattern length */
patlen = strlen(pat);
strcpy(arg->pat, pat);
if ((arg->ignore = (char) ignore) != 0)
strlwr(arg->pat);
memset(arg->delta, patlen, 256);
for (i = 0; i < patlen; ++i)
arg->delta[pat[i]] = (char) (patlen - i - 1);
if (ignore) /* tweak upper case if ignore on */
for (i = 0; i < patlen; ++i)
arg->delta[toupper(pat[i])] = (char) (patlen - i - 1);
}
/*
* bmgSearch() -> scan for match
*
* bmgSearch() performs a Boyer-Moore-Gosper search of the given buffer
* for the string described by the given search argument structure. The
* match action function "action" will be called for each match found.
* This function should return non-zero to continue searching, or 0 to
* terminate the search. bmgSearch() returns the total number of
* matches found. (NOTE: this comment appears to be incorrect)
*/
char * bmgSearch(char * buffer, size_t buflen, bmgARG *arg)
{
char *s; /* temp ptr for comparisons */
int inc, /* position increment */
patlen; /* pattern length */
size_t k; /* current buffer index */
k = (patlen = strlen(arg->pat)) - 1;
for (;;)
{
while (((inc = arg->delta[buffer[k]]) != 0) &&
((k += inc) < buflen))
;
if (k >= buflen)
break;
s = buffer + (k++ - (patlen - 1));
if (!(arg->ignore ? strnicmp(s, arg->pat, patlen) : strncmp(s, arg->pat, patlen)))
return (s);
}
return (NULL);
}
/* all the above was ripped off from the PD MSGED source by jim nutt */
char * bmgStrstr (char *find,char *in,int ignore) {
static bmgARG arg;
static char last[bmgMAXPAT + 1] = "";
int len;
char *p;
#ifdef OS2
DosEnterCritSec();
#endif
if(strcmp(last,find)) {
memset(&arg,0,sizeof(bmgARG));
memset(last,0,sizeof(last));
len = strlen(find);
strncpy(last,find,min(len,bmgMAXPAT));
bmgCompile(last,&arg,ignore);
}
p = bmgSearch(in,strlen(in),&arg);
#ifdef OS2
DosExitCritSec();
#endif
return p;
}
/*
* END of bmg.c
*/